package com.jackrain.nea.fc.dl.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.jackrain.nea.common.PostDubbleEvent;
import com.jackrain.nea.common.PostHandleEvent;
import com.jackrain.nea.common.QueryCpUtil;
import com.jackrain.nea.common.QueryUserUtil;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.fc.dl.api.WmsTranChangeSaveCmd;
import com.jackrain.nea.fc.dl.mapper.WmsOrderInMapper;
import com.jackrain.nea.fc.dl.mapper.WmsTranMapper;
import com.jackrain.nea.fc.utils.Constants;
import com.jackrain.nea.fc.utils.ObjectToUtil;
import com.jackrain.nea.fc.utils.UserInformation;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.RuntimeCompute;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.face.User;
import com.jackrain.nea.web.query.DefaultWebEvent;
import com.jackrain.nea.web.query.QuerySessionImpl;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 库存转移->FC
 * @author xuxinshuai
 * @date 2018/05/05
 */
@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version = "1.0", group = "dl")
public class WmsTranChangeSaveCmdImpl extends CommandAdapter implements WmsTranChangeSaveCmd {


    @Autowired
    PostDubbleEvent postDubbleEvent;
    @Autowired
    PostHandleEvent postHandleEvent;

    @Autowired
    QueryCpUtil postQueryEvemt;
    @Autowired
    QueryUserUtil postUserEvent;

    private Logger accesLogger = LoggerFactory.getLogger(Constants.ACCESS_PARAM_LOGGER);

    @Override
    public ValueHolder execute(HashMap map) throws NDSException {

        ValueHolder vh = new ValueHolder();
        WmsOrderInMapper wmsOrderInMapper = ApplicationContextHandle.getBean(WmsOrderInMapper.class);
        WmsTranMapper wmsTranMapper = ApplicationContextHandle.getBean(WmsTranMapper.class);

        JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(map.get("param"), "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue), Feature.OrderedField);
        if (null == param || param.size() == 0) {
            throw new NDSException("参数格式错误！");
        }
//        log.debug("----------库存转移----------" + param);
        log.info("WmsTranChangeSaveCmdImpl-->param-->{}",param);

        RuntimeCompute runtimeCompute = ApplicationContextHandle.getBean("runtimeCompute");
        runtimeCompute.startRuntime();

        JSONArray dataArray = param.getJSONArray("data");
        JSONArray succesIdArray = new JSONArray();
        JSONArray errArray = new JSONArray();
        JSONArray queryDataArray = new JSONArray();

        for (int i = 0; i < dataArray.size(); i++) {

            JSONObject dataJo = dataArray.getJSONObject(i);
            JSONObject oldJo = dataJo.getJSONObject("DL_B_TRAN");
            String billnoid = oldJo.getString("ID");
            JSONObject stateObj = new JSONObject();
            Long objid = oldJo.getLong("OBJID");
            int state = oldJo.getInteger("STATE");//执行步骤

            try {

                JSONArray itemDateArray = dataJo.getJSONArray("DL_B_TRAN_ITEM_SKU");

                for (int a = 0; a < itemDateArray.size(); a++) {

                    //翻译主表
                    JSONObject newJo = new JSONObject();
                    String wmsbillno = oldJo.getString("WMS_BILL_NO");
                    newJo.put("FROM_BILL_NO", wmsbillno);
                    newJo.put("BILL_DATE", dateToStrLong(oldJo.getDate("DATE_OUT")));
                    newJo.put("REMARK", oldJo.getString("REMARK"));
                    newJo.put("STORE_DATE", dateToStrLong(oldJo.getDate("DATE_OUT")));
                    newJo.put("DATE_OUT", dateToStrLong(oldJo.getDate("DATE_OUT")));
                    newJo.put("DATE_IN", dateToStrLong(oldJo.getDate("DATE_OUT")));

                    newJo.put("TRAN_TYPE", 1);
                    newJo.put("TRAN_FLAG", 0);
                    newJo.put("ORIG_TYPE", 3);

                    newJo.put("WMS_OUT", "Y");
                    // 由库存转移生成的调拨出库
                    newJo.put("bigint4",1);
                    //明细款
                    StringBuffer ecodeList = new StringBuffer();
                    //明细款名称
                    StringBuffer enameList = new StringBuffer();
                    //调拨数量合计
                    BigDecimal sumQtyBill = BigDecimal.ZERO;
                    //调拨金额合计
                    BigDecimal sumAmtList = BigDecimal.ZERO;
                    //品类ID集合
                    StringBuffer departIdList = new StringBuffer();

                    /*************处理明细表数据************/
                    List<String> proEcodeList = new ArrayList();
                    List<Long> departList = new ArrayList();

                    JSONArray itemArray = new JSONArray();

                    JSONArray purInItemArray = itemDateArray.getJSONArray(a);

                    for (int j = 0; j < purInItemArray.size(); j++) {

                        JSONObject oldItemJson = purInItemArray.getJSONObject(j);
                        JSONObject newItemJson = new JSONObject();

                        newItemJson.put("ID", -1);
                        newItemJson.put("ISACTIVE", "Y");

                        //商品ID
                        if (null != oldItemJson.getString("SKU")) {
                            String skuEcode = oldItemJson.getString("SKU");
                            //跨库查询
                            JSONObject whereJs = new JSONObject();
                            whereJs.put("ECODE", skuEcode);
                            whereJs.put("CP_C_DISTRIB_ID", 0);
                            JSONObject cp = postQueryEvemt.queryCP("PS_C_SKU",
                                       /*商品ID，颜色id,尺寸id,条码ID*/
                                    "PS_C_PRO_ID,PS_C_SPEC1OBJ_ID,PS_C_SPEC2OBJ_ID,ID",
                                    whereJs);

//                            log.debug("跨库查询PS_C_SKU");

                            if (null != cp) {
                                //条码ID
                                newItemJson.put("PS_C_SKU_ID", cp.getLong("ID"));
                                if (null != cp.getLong("PS_C_PRO_ID")) {
                                    //商品ID
                                    newItemJson.put("PS_C_PRO_ID", cp.getLong("PS_C_PRO_ID"));
                                    //跨库查询
                                    JSONObject whereProJs = new JSONObject();
                                    whereProJs.put("ID", cp.getLong("PS_C_PRO_ID"));
                                    whereProJs.put("CP_C_DISTRIB_ID", 0);
                                    JSONObject proHashMap = postQueryEvemt.queryCP("PS_C_PRO",
                                            "ECODE,ENAME,IMAGE,PRICELIST,NUMDIM26", whereProJs);

//                                    log.debug("跨库查询PS_C_PRO");

                                    if (null != proHashMap) {
                                        //商品编码
                                        newItemJson.put("PS_C_PRO_ECODE", proHashMap.getString("ECODE"));
                                        //商品名称
                                        newItemJson.put("PS_C_PRO_ENAME", proHashMap.getString("ENAME"));
                                        //商品图片
                                        newItemJson.put("PS_C_PRO_IMAGE", proHashMap.getString("IMAGE"));
                                        //品类ID
                                        newItemJson.put("PRO_TYPE_DEPART_ID", proHashMap.getString("NUMDIM26"));
                                        //吊牌价
                                        newItemJson.put("PRICE_LIST", proHashMap.getString("PRICELIST"));

                                    } else {
                                        throw new NDSException("商品档案 查询为空！  商品ID：" + cp.getLong("PS_C_PRO_ID"));
                                    }
                                    if (newItemJson.containsKey("PRO_TYPE_DEPART_ID") &&
                                            (null != newItemJson.getLong("PRO_TYPE_DEPART_ID"))) {
                                        //跨库查询
                                        JSONObject whereProDimJs = new JSONObject();
                                        whereProDimJs.put("ID", newItemJson.getLong("PRO_TYPE_DEPART_ID"));
                                        JSONObject proDimHashMap = postQueryEvemt.queryCP("PS_C_PRODIM_ITEM",
                                                "ECODE,ENAME", whereProDimJs);
//                                        log.debug("跨库查询PS_C_PRODIM_ITEM");
                                        //品类编码
                                        newItemJson.put("PRO_TYPE_DEPART_ECODE", proDimHashMap.getString("ECODE"));
                                        //品类名称
                                        newItemJson.put("PRO_TYPE_DEPART_ENAME", proDimHashMap.getString("ENAME"));
                                    }
                                }

                                if (null != cp.getLong("PS_C_SPEC1OBJ_ID")) {
                                    //颜色ID
                                    newItemJson.put("PS_C_CLR_ID", cp.getLong("PS_C_SPEC1OBJ_ID"));
                                    //跨库查询
                                    JSONObject whereSpecObj = new JSONObject();
                                    whereSpecObj.put("ID", cp.getLong("PS_C_SPEC1OBJ_ID"));
                                    JSONObject specobj = postQueryEvemt.queryCP("PS_C_SPECOBJ",
                                            "ENAME,ECODE", whereSpecObj);
//                                    log.debug("跨库查询PS_C_SPECOBJ");
                                    //颜色编码
                                    newItemJson.put("PS_C_CLR_ECODE", specobj.getString("ECODE"));
                                    //颜色名称
                                    newItemJson.put("PS_C_CLR_ENAME", specobj.getString("ENAME"));
                                }

                                if (null != cp.getLong("PS_C_SPEC2OBJ_ID")) {
                                    //尺寸ID
                                    newItemJson.put("PS_C_SIZE_ID", cp.getLong("PS_C_SPEC2OBJ_ID"));
                                    //跨库查询
                                    JSONObject whereSpecObj = new JSONObject();
                                    whereSpecObj.put("ID", cp.getLong("PS_C_SPEC2OBJ_ID"));
                                    JSONObject specobj = postQueryEvemt.queryCP("PS_C_SPECOBJ",
                                            "ENAME,ECODE", whereSpecObj);
//                                    log.debug("跨库查询PS_C_SPECOBJ");
                                    //尺寸编码
                                    newItemJson.put("PS_C_SIZE_ECODE", specobj.getString("ECODE"));
                                    //尺寸名称
                                    newItemJson.put("PS_C_SIZE_ENAME", specobj.getString("ENAME"));
                                }
                            } else {
                                throw new NDSException("SKU 查询为空！  sku编码：" + skuEcode);
                            }

                            newItemJson.put("IS_BF_SUPPLY", 'N');
                            newItemJson.put("PS_C_SKU_ECODE", oldItemJson.getString("SKU"));

                            if (!ObjectToUtil.isNullOREmpty(oldItemJson.getString("ORIG_ECODE"))) {
                                String storeEcode = oldItemJson.getString("ORIG_ECODE");
                                JSONObject whereJo1 = new JSONObject();
                                whereJo1.put("ECODE", storeEcode);
                                JSONObject cpmap1 = postQueryEvemt.queryCP("CP_C_STORE", "ID", whereJo1);
//                                log.debug("跨库查询CP_C_STORE1");
                                Long storeId = TypeUtils.castToLong(cpmap1.getLong("ID"));
                                newJo.put("CP_C_ORIG_ID", storeId);
                            }
                            if (!ObjectToUtil.isNullOREmpty(oldItemJson.getString("DEST_ECODE"))) {
                                String storeEcode = oldItemJson.getString("DEST_ECODE");
                                JSONObject whereJo1 = new JSONObject();
                                whereJo1.put("ECODE", storeEcode);
                                JSONObject cpmap1 = postQueryEvemt.queryCP("CP_C_STORE", "ID", whereJo1);
//                                log.debug("跨库查询CP_C_STORE2");
                                Long storeId = TypeUtils.castToLong(cpmap1.getLong("ID"));
                                newJo.put("CP_C_DEST_ID", storeId);
                            }

                            newJo.put("LOGISTICS", "0");
                            newJo.put("CP_C_ORIG_ECODE", oldItemJson.getString("ORIG_ECODE"));
                            newJo.put("CP_C_DEST_ECODE", oldItemJson.getString("DEST_ECODE"));

                        }
                        //是否缓冲补货
                        newItemJson.put("IS_BF_SUPPLY", "N");

                        newItemJson.put("QTY_OUT", oldItemJson.getBigDecimal("QTY"));
                        newItemJson.put("QTY_IN", oldItemJson.getBigDecimal("QTY"));
                        //结算价
                        newItemJson.put("SETTLEMENT_PRICE", 0);

                        if (null != newItemJson.getString("PS_C_PRO_ECODE")) {
                            String ecode = newItemJson.getString("PS_C_PRO_ECODE");
                            if (!proEcodeList.contains(ecode)) {
                                proEcodeList.add(ecode);
                                ecodeList.append(ecode + ",");
                                enameList.append(newItemJson.getString("PS_C_PRO_ENAME") + ",");
                            }
                        }

                        if (null != newItemJson.getString("PRO_TYPE_DEPART_ID")) {
                            Long departId = newItemJson.getLong("PRO_TYPE_DEPART_ID");
                            if (!departList.contains(departId)) {
                                departList.add(departId);
                                departIdList.append(departId + ",");
                            }
                        }

                        newItemJson.put("QTY_BILL", oldItemJson.getBigDecimal("QTY"));
                        newItemJson.put("AMT_BILL", oldItemJson.getBigDecimal("QTY").multiply(newItemJson.getBigDecimal("PRICE_LIST")));
                        sumQtyBill = sumQtyBill.add(newItemJson.getBigDecimal("QTY_BILL"));
                        sumAmtList = sumAmtList.add(newItemJson.getBigDecimal("AMT_BILL"));

                        itemArray.add(newItemJson);

                    }

                    if (ecodeList.length() > 0) {
                        ecodeList.deleteCharAt(ecodeList.length() - 1);
                    }
                    if (enameList.length() > 0) {
                        enameList.deleteCharAt(enameList.length() - 1);
                    }
                    if (departIdList.length() > 0) {
                        departIdList.deleteCharAt(departIdList.length() - 1);
                    }

                    //编码集合
                    newJo.put("PS_C_PRO_ECODE_LIST", ecodeList);
                    //名称集合
                    newJo.put("PS_C_PRO_ENAME_LIST", enameList);
                    //调拨数量合计
                    newJo.put("SUM_QTY_BILL", sumQtyBill);
                    //调拨金额合计
                    newJo.put("SUM_AMT_LIST", sumAmtList);
                    //品类ID集合
                    newJo.put("PRO_TYPE_DEPART_ID_LIST", departIdList);
                    //出入库总数量和金额
                    newJo.put("SUM_QTY_OUT", sumQtyBill);
                    newJo.put("SUM_QTY_IN", sumQtyBill);
                    newJo.put("SUM_AMT_LIST_OUT", sumAmtList);
                    newJo.put("SUM_AMT_LIST_IN", sumAmtList);


                    User user = postUserEvent.getUser(UserInformation.USER_NAME);
                    JSONObject fixColumn = new JSONObject();
                    fixColumn.put("DL_B_TRAN_OUT", newJo);
                    fixColumn.put("DL_B_TRAN_OUT_V_ITEM_SKU", itemArray);

                    JSONObject resultJson = new JSONObject();
                    resultJson.put("objid", -1);
                    resultJson.put("fixcolumn", fixColumn);
                    resultJson.put("table", "DL_B_TRAN_OUT");
                    resultJson.put("isWMSCheck", "N");
                    accesLogger.info("WmsTranChangeSaveCmdImpl--resultJson_save-->{}",resultJson);
//                    log.info("resultJson==>" + resultJson.toString());
                    QuerySessionImpl querySession = new QuerySessionImpl(user);
                    DefaultWebEvent event = new DefaultWebEvent("dlOrderIn", new HashMap(16));
                    event.put("param", resultJson);

                    event.setParameter("command", "com.jackrain.nea.dl.tran.api.BtranoutbufferSaveCmd:1.0:dl");
                    event.setParameter("table", "DL_B_TRAN_OUT");

                    querySession.setEvent(event);
                    //1.保存服务
//                    if (0 == state) {
                    JSONObject retJo = postHandleEvent.executePostHandle(resultJson, querySession, event, "save");
                    accesLogger.info("WmsTranChangeSaveCmdImpl--retJo-->{}",retJo);

                    if (retJo.get("code") != null && (int) retJo.get("code") < 0) {
                        throw new NDSException("保存失败:" + retJo.get("message") + retJo.get("error") + retJo.get("data"));
                    }
                    objid = retJo.getLong("objid");
                    if (objid == null) {
                        JSONObject retData = retJo.getJSONObject("data");
                        objid = retData.getLong("objid");
                    }
                    state = 1;
                    stateObj.put("objid", objid);
                    stateObj.put("state", state);
                    queryDataArray.add(resultJson);
//                    }
                    //2.提交服务
//                    if (1 == state) {
                    resultJson.put("objid", objid);
                    event.put("param", resultJson);
                    accesLogger.info("WmsTranChangeSaveCmdImpl--resultJson_submit-->{}",resultJson);

                    event.setParameter("command", "com.jackrain.nea.dl.tran.api.BtranoutSumbitCmd:1.0:dl");
                    event.setParameter("table", "DL_B_TRAN_OUT");
                    querySession.setEvent(event);
                    JSONObject subJo = postHandleEvent.executePostHandle(resultJson, querySession, event, "submit");
                    accesLogger.info("WmsTranChangeSaveCmdImpl--subJo-->{}",subJo);

                    if (subJo.get("code") != null && (int) subJo.get("code") < 0) {
                        throw new NDSException("提交失败:" + subJo.get("message") + subJo.get("error") + subJo.get("data"));
                    }
                    state = 2;
                    stateObj.put("objid", objid);
                    stateObj.put("state", state);
//                    }
                    //3.发出服务
//                    if (2 == state) {
                    resultJson.put("objid", objid);
                    accesLogger.info("WmsTranChangeSaveCmdImpl--resultJson_sendout-->{}",resultJson);
//                    log.debug("----------库存转移发出参数----------" + resultJson);
                    event.put("param", resultJson);
                    event.setParameter("command", "com.jackrain.nea.dl.tran.api.BtranoutSendCmd:1.0:dl");
                    event.setParameter("table", "DL_B_TRAN_OUT");
                    event.setParameter("webaction", "DL_B_TRAN_OUT_SEND_TRAFFIC_CONFIRM");
                    querySession.setEvent(event);
                    JSONObject SendJo = postHandleEvent.executePostHandle(resultJson, querySession, event, "webaction");
                    accesLogger.info("WmsTranChangeSaveCmdImpl--SendJo-->{}",SendJo);

                    if (SendJo.get("code") != null && (int) SendJo.get("code") < 0) {
                        throw new NDSException("发出失败:" + SendJo.get("message") + SendJo.get("error") + SendJo.get("data"));
                    }
                    state = 3;
                    stateObj.put("objid", objid);
                    stateObj.put("state", state);
//                    }
                    //===========验收服务==============
                    //查询 QTY_OUT 赋值QTY_IN
                    List<HashMap> qtyList = wmsTranMapper.selectQtyId(objid);
                    JSONArray qtyArrray = listToJsonarray(qtyList);
                    //4.调用保存服务
                    QuerySessionImpl tranquerySession = new QuerySessionImpl(user);
                    DefaultWebEvent tranevent = new DefaultWebEvent("dltranIn", new HashMap(16));
                    JSONObject tranJo = new JSONObject();
                    tranJo.put("objid", objid);
                    tranJo.put("isWMSCheck", "N");
                    JSONObject tranIn = new JSONObject();
                    JSONObject fixColumJo = new JSONObject();
                    fixColumJo.put("DL_B_TRAN_IN", tranIn);
                    fixColumJo.put("DL_B_TRAN_IN_V_ITEM_SKU", qtyArrray);
                    tranJo.put("fixcolumn", fixColumJo);
                    tranJo.put("table", "DL_B_TRAN_IN");
                    tranevent.put("param", tranJo);
                    tranquerySession.setEvent(tranevent);

//                    if (3 == state) {

//                    JSONObject tranretJo = postHandleEvent.executePostHandle(tranJo, tranquerySession, tranevent, "save");
//                    if (tranretJo.get("code") != null && (int) tranretJo.get("code") < 0) {
//                        throw new NDSException("DL_B_TRAN_IN保存失败:" + tranretJo.get("message") + tranretJo.get("error") + tranretJo.get("data"));
//                    }
                    state = 4;
                    stateObj.put("objid", objid);
                    stateObj.put("state", state);
//                    }
                    //5.调用验收服务
                    tranevent.setParameter("command", "com.jackrain.nea.dl.tran.api.BtraninCheckInCmd:1.0:dl");
                    tranevent.setParameter("table", "DL_B_TRAN_IN");
                    tranevent.setParameter("webaction", "DL_B_TRAN_IN_CHECK_S");
                    tranquerySession.setEvent(tranevent);
                    accesLogger.info("WmsTranChangeSaveCmdImpl--tranJo-->{}",tranJo);
                    JSONObject accJo = postHandleEvent.executePostHandle(tranJo, tranquerySession, tranevent, "webaction");
                    accesLogger.info("WmsTranChangeSaveCmdImpl--accJo-->{}",accJo);

                    if (accJo.get("code") != null && (int) accJo.get("code") < 0) {
                        throw new NDSException("验收失败:" + accJo.get("message") + accJo.get("error") + accJo.get("data"));
                    }

                    state = 5;
                    stateObj.put("id", billnoid);
                    stateObj.put("objid", objid);
                    stateObj.put("state", state);
                    succesIdArray.add(stateObj);
                }

            } catch (Exception e) {

                JSONObject errrobj = new JSONObject();
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                e.printStackTrace(pw);
                if (e instanceof NDSException) {
                    errrobj.put("message", e.getMessage());
                } else {
                    errrobj.put("message", sw.toString());
                }
                errrobj.put("id", billnoid);
                errrobj.put("state", state);
                errrobj.put("objid", objid);
                errArray.add(errrobj);
            }
        }

        if (errArray.size() > 0) {
            vh.put("error", errArray);
            vh.put("success", succesIdArray);
            vh.put("code", -1);
        } else {
            vh.put("success", succesIdArray);
            vh.put("code", 0);
        }
        vh.put("queryDataArray",queryDataArray);
        Double spendTime = runtimeCompute.endRuntime();
        vh.put("spendtime", spendTime);
//        log.debug("---------库存转移执行时间--------->>" + spendTime);
        return vh;

    }

    /**
     * list TO jsonarra
     *
     * @param mapList
     * @return jsonArray
     */
    public JSONArray listToJsonarray(List<HashMap> mapList) {
        JSONArray jsonArray = new JSONArray();
        for (int i = 0; i < mapList.size(); i++) {
            HashMap map = (HashMap) mapList.get(i);
            JSONObject jsonObject = new JSONObject(map);
            JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(jsonObject, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue), Feature.OrderedField);
            jsonArray.add(param);
        }
        return jsonArray;
    }

    /**
     * 将长时间格式时间转换为字符串 yyyy-MM-dd HH:mm:ss
     *
     * @param dateDate
     * @return
     */
    public static String dateToStrLong(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        String dateString = formatter.format(dateDate);
        return dateString;
    }

}
